package com.qys.livesMall.app.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.app.user.event.UserLeveEditEvent;
import com.qys.livesMall.app.user.mapper.AppUserLevelMapper;
import com.qys.livesMall.app.user.mapper.H2AppUserRechargeWithdrawalsMapper;
import com.qys.livesMall.app.user.model.dto.sys.UserLeveEditEventDTO;
import com.qys.livesMall.app.user.model.dto.sys.UserLevelDTO;
import com.qys.livesMall.app.user.model.dto.sys.UserLevelUpgradationDTO;
import com.qys.livesMall.app.user.model.entity.AppUserLevel;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.model.entity.UserRewardConfig;
import com.qys.livesMall.app.user.model.entity.UserRewardHistory;
import com.qys.livesMall.app.user.service.*;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.utils.MessageUtils;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.model.dto.FinancePayDTO;
import com.qys.livesMall.finance.service.FinanceBusinessService;
import com.qys.livesMall.finance.util.BusinessNoUtil;
import com.qys.livesMall.framework.utils.SecurityUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author
 * @since 2023-06-06
 */
@Service
@Slf4j
public class AppUserLevelServiceImpl extends ServiceImpl<AppUserLevelMapper, AppUserLevel> implements AppUserLevelService {

    @Resource
    private IH2AppUserService appUserService;
    @Autowired
    private AppUserRelationService relationService;
    @Resource
    private H2AppUserRechargeWithdrawalsMapper h2AppUserRechargeWithdrawalsMapper;
    @Resource
    private UserRewardHistoryService userRewardHistoryService;
    @Resource
    private UserRewardConfigService userRewardConfigService;
    @Resource
    private FinanceBusinessService financeBusinessService;
    @Resource
    private ApplicationContext applicationContext;
    /**
     * 新增用户等级信息
     *
     * @param userLevelDTO
     */
    @Override
    public void save(UserLevelDTO userLevelDTO) {
        //是否有相同等级
        List<AppUserLevel> levelList = baseMapper.selectList(Wrappers.<AppUserLevel>query().eq("level", userLevelDTO.getLevel()));
        if (CollectionUtils.isNotEmpty(levelList)) {
            throw new QysException(MessageUtils.message("user.level.exist"));
        }

        //查询最大的id
        Integer maxLevelId = baseMapper.queryMaxId();

        AppUserLevel userLevel = new AppUserLevel();
        BeanUtils.copyProperties(userLevelDTO, userLevel);
        userLevel.setParentLevel(maxLevelId);
        userLevel.setCreateBy(SecurityUtils.getUsername());
        userLevel.setCreateTime(LocalDateTime.now());
        baseMapper.insert(userLevel);
    }

    /**
     * 修改用户等级
     *
     * @param userLevelDTO
     */
    @Override
    public void editById(UserLevelDTO userLevelDTO) {
        AppUserLevel userLevel = baseMapper.selectById(userLevelDTO.getId());
        if (null == userLevel) {
            throw new QysException(MessageUtils.message("user.level.not.found"));
        }

        BeanUtils.copyProperties(userLevelDTO, userLevel);
        userLevel.setUpdateBy(SecurityUtils.getUsername());
        userLevel.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(userLevel);
    }

    /**
     * 删除用户等级信息
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Integer id) {
        AppUserLevel userLevel = baseMapper.selectById(id);
        if (null == userLevel) {
            throw new QysException(MessageUtils.message("user.level.not.found"));
        }

        //下级信息
        AppUserLevel child = baseMapper.selectOne(Wrappers.<AppUserLevel>query().eq("parent_level", userLevel.getLevel()));
        if (null != child) {
            throw new QysException(MessageUtils.message("user.level.remove.last"));
        }

        //删除当前节点
        baseMapper.deleteById(id);
    }

    @Override
    public void adjustUserLevel(Long userId) {
        log.info("触发用户等级变更, userId:{}", userId);
        //用户充值总额金额
        BigDecimal rechargeAmount=h2AppUserRechargeWithdrawalsMapper.getRechargeAmount(Arrays.asList(userId));
        BigDecimal newRechargeAmount  = rechargeAmount == null? BigDecimal.ZERO : rechargeAmount;
        //匹配合适的等级
        H2AppUser oldAppUser = appUserService.getById(userId);
        LambdaQueryWrapper<AppUserLevel> levelLambdaQueryWrapper=new LambdaQueryWrapper<>();
        levelLambdaQueryWrapper.gt(AppUserLevel::getLevel,oldAppUser.getUserLevelId());
        List<AppUserLevel> levelS = list(levelLambdaQueryWrapper);
        List<AppUserLevel> newLevelS = levelS.stream().filter(e -> newRechargeAmount.compareTo(e.getRechargeAmount()) >= 0
        ).sorted(Comparator.comparing(AppUserLevel::getLevel).reversed()).toList();
        if(CollectionUtils.isEmpty(newLevelS)){
            return ;
        }
        //邀请直属人数
        List<H2AppUser> directusersList = relationService.getLowerLevels(userId,1);
        List<Long> directUserids=directusersList.stream().map(a->Long.parseLong(a.getId())).collect(Collectors.toList());
        //邀请非直属人数
        List<H2AppUser> notDirectusersList = relationService.getGreaterLevels(userId,1);
        List<Long> notDirecUserids=notDirectusersList.stream().map(a->Long.parseLong(a.getId())).collect(Collectors.toList());

        LambdaQueryWrapper<UserRewardConfig> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(UserRewardConfig::getAwardType,8);
        wrapper.last("limit 1");
        UserRewardConfig userRewardConfig=userRewardConfigService.getOne(wrapper);
        for (int i = 0; i < newLevelS.size(); i++) {
            AppUserLevel appUserLevel=newLevelS.get(i);
            if(oldAppUser.getUserLevelId() != null && oldAppUser.getUserLevelId() > appUserLevel.getLevel()){
                continue;
            }
            //有效直属人数
            Integer resultDirectusers =0;
            if (CollectionUtils.isNotEmpty(directUserids)){
                resultDirectusers = h2AppUserRechargeWithdrawalsMapper.getSatisfyRechargeNmu(directUserids,appUserLevel.getEffectiveRechargeAmount());
            }
            //有效非直属人数
            Integer resultNotDirectusers =0;
            if (CollectionUtils.isNotEmpty(notDirecUserids)){
                resultNotDirectusers = h2AppUserRechargeWithdrawalsMapper.getSatisfyRechargeNmu(notDirecUserids,appUserLevel.getEffectiveRechargeAmount());
            }
            if (resultDirectusers < appUserLevel.getUpgradeConditionNum() || resultNotDirectusers < appUserLevel.getInviteNonDirect()){
                continue;
            }
            H2AppUser appUser = new H2AppUser();
            appUser.setId(String.valueOf(userId));
            appUser.setUserLevelId(Long.valueOf(appUserLevel.getLevel()));
            appUser.setUserLevel(appUserLevel.getName());
            appUserService.updateById(appUser);
            log.info("用户等级变更成功, userId:{}, balance:{}", userId, rechargeAmount);
            //更新用户层级关系
            if ( oldAppUser.getStatus()==0  && oldAppUser.getUserSysType() !=0 && oldAppUser.getUserLevelId().intValue()==0 && appUserLevel.getLevel()>=1){
                UserLeveEditEventDTO userLeveEditEventDTO=new UserLeveEditEventDTO();
                userLeveEditEventDTO.setUserId(userId);
                applicationContext.publishEvent(new UserLeveEditEvent(userLeveEditEventDTO));
            }
            if (null == userRewardConfig){
                break;
            }
            //升级奖励
            LambdaQueryWrapper<UserRewardHistory> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.eq(UserRewardHistory::getUserId,userId);
            queryWrapper.eq(UserRewardHistory::getType, AccountBusinessTypeEnum.USER_LEVEL_UPGRADE_REWARDS.getType());
            queryWrapper.eq(UserRewardHistory::getCorrespondingId,appUserLevel.getId());
            List<UserRewardHistory> list=userRewardHistoryService.list(queryWrapper);
            if (CollectionUtils.isEmpty(list)){
                FinancePayDTO payDTO = new FinancePayDTO();
                payDTO.setUserId(userId);
                payDTO.setBusinessNo(BusinessNoUtil.get(AccountBusinessTypeEnum.USER_LEVEL_UPGRADE_REWARDS));
                payDTO.setAmountIncurred(userRewardConfig.getAwardUnit().multiply(new BigDecimal(appUserLevel.getLevel())));
                payDTO.setBusinessType(AccountBusinessTypeEnum.USER_LEVEL_UPGRADE_REWARDS);
                financeBusinessService.pay(payDTO);
                if (!payDTO.getSuccess()){
                    throw new QysException(payDTO.getMessage());
                }
                //保存升级奖励记录
                UserRewardHistory userRewardHistory=new UserRewardHistory();
                userRewardHistory.setUserId(userId);
                userRewardHistory.setType(AccountBusinessTypeEnum.USER_LEVEL_UPGRADE_REWARDS.getType());
                userRewardHistory.setMoney(userRewardConfig.getAwardUnit().multiply(new BigDecimal(appUserLevel.getLevel())));
                userRewardHistory.setCorrespondingId(Long.valueOf(appUserLevel.getId()));
                userRewardHistoryService.save(userRewardHistory);
            }
            break;
        }
        //递归查询 所有上级是否会因为非直属升级
        H2AppUser h2AppUser = appUserService.getById(userId);
        if (null != h2AppUser.getSuperior()){
            this.adjustUserLevel(h2AppUser.getSuperior());
        }
    }

    @Override
    public void saveUpgradation(UserLevelUpgradationDTO upgradationDTO) {
        //是否有相同等级
        List<AppUserLevel> levelList = baseMapper.selectList(Wrappers.<AppUserLevel>query().eq("level", upgradationDTO.getLevel()));
        if (CollectionUtils.isNotEmpty(levelList)) {
            throw new QysException(MessageUtils.message("user.level.exist"));
        }

        //查询最大的id
        Integer maxLevelId = baseMapper.queryMaxId();

        AppUserLevel userLevel = new AppUserLevel();
        BeanUtils.copyProperties(upgradationDTO, userLevel);
        userLevel.setParentLevel(maxLevelId);
        userLevel.setCreateBy(SecurityUtils.getUsername());
        userLevel.setCreateTime(LocalDateTime.now());
        baseMapper.insert(userLevel);
    }

    @Override
    public void editUpgradationById(UserLevelUpgradationDTO upgradationDTO) {
        AppUserLevel userLevel = baseMapper.selectById(upgradationDTO.getId());
        if (null == userLevel) {
            throw new QysException(MessageUtils.message("user.level.not.found"));
        }
        BeanUtils.copyProperties(upgradationDTO, userLevel);
        userLevel.setUpdateBy(SecurityUtils.getUsername());
        userLevel.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(userLevel);
    }
}
